package com.zapi.workflow.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zapi.entity.User;
import com.zapi.service.UserService;
import com.zapi.workflow.service.mapper.WfHistoryActivityMapper;
import com.zapi.workflow.service.model.dto.CcDisplayDTO;
import com.zapi.workflow.service.model.dto.CompletedTaskDisplayDTO;
import com.zapi.workflow.service.model.entity.WfHistoryActivity;
import com.zapi.workflow.service.service.WfHistoryActivityService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 流程活动历史服务实现类
 * 实现流程历史记录的具体业务逻辑
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WfHistoryActivityServiceImpl extends ServiceImpl<WfHistoryActivityMapper, WfHistoryActivity> 
        implements WfHistoryActivityService {

    private final UserService userService;

    @Override
    public WfHistoryActivity recordActivityStart(String processInstanceId, String nodeId, 
                                               String nodeName, String nodeType, String operator) {
        log.info("记录流程活动开始: processInstanceId={}, nodeId={}, nodeType={}", 
                processInstanceId, nodeId, nodeType);
        
        WfHistoryActivity activity = new WfHistoryActivity();
        activity.setProcessInstanceId(processInstanceId);
        activity.setNodeId(nodeId);
        activity.setNodeName(nodeName);
        activity.setNodeType(nodeType);
        activity.setStartTime(LocalDateTime.now());
        activity.setOperator(operator);
        
        baseMapper.insert(activity);
        
        log.info("流程活动开始记录完成: activityId={}", activity.getId());
        return activity;
    }

    @Override
    public void recordActivityEnd(String processInstanceId, String nodeId, String operator, String comment) {
        log.info("记录流程活动结束: processInstanceId={}, nodeId={}", processInstanceId, nodeId);
        
        // 查找对应的开始记录
        LambdaQueryWrapper<WfHistoryActivity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WfHistoryActivity::getProcessInstanceId, processInstanceId)
                   .eq(WfHistoryActivity::getNodeId, nodeId)
                   .isNull(WfHistoryActivity::getEndTime)
                   .orderByDesc(WfHistoryActivity::getStartTime)
                   .last("LIMIT 1");
        
        WfHistoryActivity activity = baseMapper.selectOne(queryWrapper);
        
        if (activity != null) {
            LocalDateTime endTime = LocalDateTime.now();
            activity.setEndTime(endTime);
            activity.setOperator(operator);
            activity.setComment(comment);
            
            // 计算耗时（毫秒）
            if (activity.getStartTime() != null) {
                long duration = java.time.Duration.between(activity.getStartTime(), endTime).toMillis();
                activity.setDuration(duration);
            }
            
            baseMapper.updateById(activity);
            log.info("流程活动结束记录完成: activityId={}, duration={}ms", activity.getId(), activity.getDuration());
        } else {
            log.warn("未找到对应的活动开始记录: processInstanceId={}, nodeId={}", processInstanceId, nodeId);
        }
    }

    @Override
    public WfHistoryActivity recordCompleteActivity(String processInstanceId, String nodeId, 
                                                  String nodeName, String nodeType, String operator, String comment) {
        log.info("记录完整流程活动: processInstanceId={}, nodeId={}, nodeType={}", 
                processInstanceId, nodeId, nodeType);
        
        LocalDateTime now = LocalDateTime.now();
        
        WfHistoryActivity activity = new WfHistoryActivity();
        activity.setProcessInstanceId(processInstanceId);
        activity.setNodeId(nodeId);
        activity.setNodeName(nodeName);
        activity.setNodeType(nodeType);
        activity.setStartTime(now);
        activity.setEndTime(now);
        activity.setDuration(0L); // 瞬时完成
        activity.setOperator(operator);
        activity.setComment(comment);
        
        baseMapper.insert(activity);
        
        log.info("完整流程活动记录完成: activityId={}", activity.getId());
        return activity;
    }

    @Override
    public List<WfHistoryActivity> getProcessInstanceHistory(String processInstanceId) {
        log.debug("获取流程实例历史: processInstanceId={}", processInstanceId);
        return baseMapper.selectByProcessInstanceId(processInstanceId);
    }

    @Override
    public WfHistoryActivity getCurrentActivity(String processInstanceId) {
        log.debug("获取流程实例当前活动: processInstanceId={}", processInstanceId);
        return baseMapper.selectLatestByProcessInstanceId(processInstanceId);
    }

    @Override
    public boolean isNodeCompleted(String processInstanceId, String nodeId) {
        LambdaQueryWrapper<WfHistoryActivity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WfHistoryActivity::getProcessInstanceId, processInstanceId)
                   .eq(WfHistoryActivity::getNodeId, nodeId)
                   .isNotNull(WfHistoryActivity::getEndTime);
        
        List<WfHistoryActivity> activities = baseMapper.selectList(queryWrapper);
        boolean completed = !activities.isEmpty();
        
        log.debug("检查节点完成状态: processInstanceId={}, nodeId={}, completed={}", 
                processInstanceId, nodeId, completed);
        
        return completed;
    }

    @Override
    public IPage<CcDisplayDTO> getUserCcRecordsWithDisplayInfo(Page<CcDisplayDTO> page, String ccUser) {
        log.debug("查询用户抄送记录: ccUser={}, pageNum={}, pageSize={}", 
                ccUser, page.getCurrent(), page.getSize());
        
        // 1. 查询抄送记录
        IPage<CcDisplayDTO> result = baseMapper.selectUserCcRecordsWithDisplayInfo(page, ccUser);
        
        // 2. 填充用户名称和表单名称
        List<CcDisplayDTO> displayList = result.getRecords().stream()
                .map(this::enrichCcDisplayDTO)
                .collect(Collectors.toList());
        
        result.setRecords(displayList);
        
        log.info("查询用户抄送记录完成: ccUser={}, total={}", ccUser, result.getTotal());
        return result;
    }
    
    /**
     * 丰富抄送显示DTO信息
     */
    private CcDisplayDTO enrichCcDisplayDTO(CcDisplayDTO dto) {
        try {
            // 设置抄送接收人（从comment中提取或直接使用）
            dto.setCcUser(extractCcUserFromComment(dto.getComment()));
            
            // 获取发起人真实姓名
            dto.setStartUserName(getUserRealName(dto.getStartUser()));
            
            // 获取抄送接收人真实姓名
            dto.setCcUserName(getUserRealName(dto.getCcUser()));
            
            // 设置表单名称
            if (dto.getBusinessType() != null) {
                if (dto.getBusinessType() == 1) {
                    // 系统表单
                    String formName = dto.getSystemFormKey() != null ? 
                        "系统表单(" + dto.getSystemFormKey() + ")" : "系统表单(未配置)";
                    dto.setFormName(formName);
                } else if (dto.getBusinessType() == 2) {
                    // 自定义表单
                    String formName = dto.getBusinessFormId() != null ? 
                        "自定义表单(" + dto.getBusinessFormId() + ")" : "自定义表单(未配置)";
                    dto.setFormName(formName);
                } else {
                    dto.setFormName("未配置表单");
                }
            } else {
                dto.setFormName("未配置表单");
            }
            
            // 从comment中提取通知方式和是否需要确认阅读
            extractNotifyInfoFromComment(dto);
            
        } catch (Exception e) {
            log.warn("丰富抄送显示DTO信息失败: ccRecordId={}, error={}", dto.getId(), e.getMessage());
            dto.setStartUserName("未知");
            dto.setCcUserName("未知");
            dto.setFormName("加载失败");
        }
        
        return dto;
    }
    
    /**
     * 从comment中提取抄送接收人
     */
    private String extractCcUserFromComment(String comment) {
        if (comment == null || comment.isEmpty()) {
            return null;
        }
        
        // 从"接收人: xxx"中提取用户ID
        int startIndex = comment.indexOf("接收人: ");
        if (startIndex != -1) {
            startIndex += "接收人: ".length();
            int endIndex = comment.indexOf("，", startIndex);
            if (endIndex == -1) {
                endIndex = comment.indexOf(",", startIndex);
            }
            if (endIndex == -1) {
                endIndex = comment.length();
            }
            return comment.substring(startIndex, endIndex).trim();
        }
        
        return null;
    }
    
    /**
     * 从comment中提取通知方式和是否需要确认阅读
     */
    private void extractNotifyInfoFromComment(CcDisplayDTO dto) {
        String comment = dto.getComment();
        if (comment == null || comment.isEmpty()) {
            return;
        }
        
        // 提取通知方式
        int notifyIndex = comment.indexOf("方式: ");
        if (notifyIndex != -1) {
            notifyIndex += "方式: ".length();
            int endIndex = comment.indexOf("，", notifyIndex);
            if (endIndex == -1) {
                endIndex = comment.indexOf(",", notifyIndex);
            }
            if (endIndex == -1) {
                endIndex = comment.length();
            }
            dto.setNotifyType(comment.substring(notifyIndex, endIndex).trim());
        }
        
        // 检查是否需要确认阅读
        dto.setRequireRead(comment.contains("需确认阅读"));
    }
    
    /**
     * 根据用户ID获取真实姓名
     */
    private String getUserRealName(String userId) {
        if (userId == null || userId.trim().isEmpty()) {
            return "未知用户";
        }
        
        try {
            // 尝试将userId转换为Long类型
            Long userIdLong = Long.parseLong(userId);
            User user = userService.getById(userIdLong);
            if (user != null && user.getRealName() != null && !user.getRealName().trim().isEmpty()) {
                return user.getRealName();
            }
        } catch (NumberFormatException e) {
            // 如果userId不是数字，尝试通过用户名查询
            User user = userService.findByUsername(userId);
            if (user != null && user.getRealName() != null && !user.getRealName().trim().isEmpty()) {
                return user.getRealName();
            }
        } catch (Exception e) {
            // 查询失败，返回用户ID
            log.debug("查询用户真实姓名失败: userId={}, error={}", userId, e.getMessage());
        }
        
        // 如果查询失败或没有真实姓名，返回用户ID
        return userId;
    }
    
    @Override
    public IPage<CompletedTaskDisplayDTO> getUserCompletedTasksWithDisplayInfo(Page<CompletedTaskDisplayDTO> page, String operator) {
        log.debug("查询用户已办任务: operator={}, pageNum={}, pageSize={}", 
                operator, page.getCurrent(), page.getSize());
        
        // 1. 查询已办任务
        IPage<CompletedTaskDisplayDTO> result = baseMapper.selectUserCompletedTasksWithDisplayInfo(page, operator);
        
        // 2. 填充用户名称和表单名称
        List<CompletedTaskDisplayDTO> displayList = result.getRecords().stream()
                .map(this::enrichCompletedTaskDisplayDTO)
                .collect(Collectors.toList());
        
        result.setRecords(displayList);
        
        log.info("查询用户已办任务完成: operator={}, total={}", operator, result.getTotal());
        return result;
    }
    
    /**
     * 丰富已办任务显示DTO信息
     */
    private CompletedTaskDisplayDTO enrichCompletedTaskDisplayDTO(CompletedTaskDisplayDTO dto) {
        try {
            // 获取发起人真实姓名
            dto.setStartUserName(getUserRealName(dto.getStartUser()));
            
            // 获取操作人真实姓名
            dto.setOperatorName(getUserRealName(dto.getOperator()));
            
            // 设置表单名称
            if (dto.getBusinessType() != null) {
                if (dto.getBusinessType() == 1) {
                    // 系统表单
                    String formName = dto.getSystemFormKey() != null ? 
                        "系统表单(" + dto.getSystemFormKey() + ")" : "系统表单(未配置)";
                    dto.setFormName(formName);
                } else if (dto.getBusinessType() == 2) {
                    // 自定义表单
                    String formName = dto.getBusinessFormId() != null ? 
                        "自定义表单(" + dto.getBusinessFormId() + ")" : "自定义表单(未配置)";
                    dto.setFormName(formName);
                } else {
                    dto.setFormName("未配置表单");
                }
            } else {
                dto.setFormName("未配置表单");
            }
            
        } catch (Exception e) {
            log.warn("丰富已办任务显示DTO信息失败: taskId={}, error={}", dto.getId(), e.getMessage());
            dto.setStartUserName("未知");
            dto.setOperatorName("未知");
            dto.setFormName("加载失败");
        }
        
        return dto;
    }
}